<template>
    <div class="map">
        <div class="wrapper">
            <el-button type="primary" size="small" @click="goBack"
                >返回</el-button
            >
            <el-button type="primary" size="small" @click="clickReset"
                >重置</el-button
            >
            <div class="info">{{ currentLocation }}</div>
        </div>
        <div id="mapId" class="map-container"></div>
    </div>
</template>

<script>
import echarts from "echarts";
import axios from "axios";
export default {
    name: "mapComponent",
    components: {},
    mounted() {
        this.myChart = echarts.init(document.getElementById("mapId"));
        this.initChinaMap();
        this.myChart.on("click", (params) => {
            const type = params.componentSubType;
            if (type === "effectScatter" || type === "lines") {
                // 点击到飞线或图标不处理
                return;
            }
            if (!params.data) return;
            const { adcode, name, level } = params.data;
            if (level === "district") {
                this.$message.info("无此区域地图显示！");
                return;
            }
            this.highLightArea.push(name);
            this.mapList.push({ name, adcode });
            this.handleNavName();
            this.getGeoJsonData({ name, adcode }, (data) => {
                this.renderChart(name, data);
            });
        });
    },
    destroyed() {
        const chart = echarts.getInstanceByDom(
            document.getElementById("mapId")
        );
        if (chart) {
            echarts.dispose(chart);
        }
    },
    data() {
        return {
            myChart: "",
            currentLocation: "中国",
            mapList: [{ name: "中国", adcode: 100000 }],
            highLightArea: [],
        };
    },
    methods: {
        initChinaMap() {
            this.currentLocation = this.$options.data().currentLocation;
            this.mapList = this.$options.data().mapList;
            this.getGeoJsonData({ name: "china", adcode: 100000 }, (data) => {
                this.renderChart("china", data);
            });
        },
        // 获取json数据
        getGeoJsonData({ name, adcode = "100000" }, callback) {
            const url = `https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=${adcode}_full`;
            axios
                .get(url, {
                    headers: {
                        "Content-Type": "application/json;charset=UTF-8",
                    },
                })
                .then((response) => {
                    callback && callback(response.data);
                })
                .catch((error) => {
                    console.log(error);
                });
        },
        renderChart(name, data) {
            // 注册地图
            echarts.registerMap(name, data);
            const mapData = data.features.map((item) => item.properties);
            const planePath =
                "path://M1705.06,1318.313v-89.254l-319.9-221.799l0.073-208.063c0.521-84.662-26.629-121.796-63.961-121.491c-37.332-0.305-64.482,36.829-63.961,121.491l0.073,208.063l-319.9,221.799v89.254l330.343-157.288l12.238,241.308l-134.449,92.931l0.531,42.034l175.125-42.917l175.125,42.917l0.531-42.034l-134.449-92.931l12.238-241.308L1705.06,1318.313z";
            const showFlag = this.mapList.length === 1; // 仅在“国”层显示飞线，下钻不显示
            const option = {
                tooltip: {
                    formatter: function (params) {
                        if (params?.data) {
                            const { adcode, name, level } = params.data;
                            return `adcode: ${adcode}<br>level: ${level}<br>name: ${name}`;
                        }
                    },
                },
                // 地理坐标系组件用于地图的绘制
                geo: [
                    {
                        map: name,
                        zoom: 1.2,
                        roam: true, // 缩放和平移,默认不开启。scale/move为只开启缩放/平移，true为都开启
                        selectedMode: "single", // 图形上的文本标签，可用于说明图形的一些数据信息，比如值，名称等。
                        label: {
                            show: true,
                            color: "#666666",
                            fontSize: 10,
                        },
                        itemStyle: {
                            areaColor: "#71d5a1", // 地图区域颜色
                            borderColor: "#2979ff",
                        },
                        animationDurationUpdate: 0, //地图移动的时候，渲染的点跟着移动，但是会有延迟，设置为0，则没有延迟
                        // 设置高亮状态下的多边形和标签样式
                        emphasis: {
                            itemStyle: {
                                areaColor: "#ffff99",
                                borderColor: "#f29100",
                            },
                            label: {
                                fontSize: 16,
                                color: "#f29100",
                            },
                        },
                    },
                ],
                series: [
                    // 地图配置
                    {
                        type: "map",
                        map: name,
                        geoIndex: 0,
                        roam: true,
                        data: mapData,
                    },
                    // 飞线图配置
                    {
                        type: "effectScatter",
                        coordinateSystem: "geo",
                        zlevel: 1,
                        rippleEffect: {
                            //涟漪特效
                            period: 4, //动画时间，值越小速度越快
                            brushType: "stroke", //波纹绘制方式 stroke, fill
                            scale: showFlag ? 4 : 0, //波纹圆环最大限制，值越大波纹越大
                        },
                        emphasis: {
                            position: "right", //显示位置
                            offset: [5, 0], //偏移设置
                            formatter: (params) => params.data.name, //圆环显示文字
                            fontSize: 13,
                        },
                        symbol: "circle",
                        symbolSize: (val) => (showFlag ? 5 : 0), //圆环大小
                        // symbolSize: (val) => 5 + val[2] * 5, //圆环大小
                        itemStyle: {
                            show: false,
                            color: "#ff6c37",
                        },
                        data: [
                            { name: "重庆", value: [106.33, 29.35] },
                            { name: "新疆", value: [86, 40] },
                            {
                                name: "上海",
                                value: [121.480509, 31.23592, 100],
                            },
                            {
                                name: "北京",
                                value: [116.403039, 39.914023, 100],
                            },
                        ],
                    },
                    {
                        type: "lines",
                        zlevel: 1,
                        coordinateSystem: "geo",
                        effect: {
                            color: "#ff0000",
                            show: showFlag ? true : false,
                            period: 6, //箭头指向速度，值越小速度越快
                            trailLength: 0, //特效尾迹长度[0,1]值越大，尾迹越长重
                            symbol: planePath, //箭头图标
                            // symbol: "arrow", //箭头图标
                            symbolSize: 15, //图标大小
                        },
                        lineStyle: {
                            color: "#ffeb4c",
                            width: 1, //尾迹线条宽度
                            opacity: showFlag ? 0.7 : 0, //尾迹线条透明度
                            curveness: 0.2, //尾迹线条曲直度
                        },
                        data: [
                            // 重庆-新疆
                            {
                                coords: [
                                    [86, 40],
                                    [106.33, 29.35],
                                ],
                            },
                            // 重庆-上海
                            {
                                coords: [
                                    [121.480509, 31.23592],
                                    [106.33, 29.35],
                                ],
                            },
                            // 重庆-北京
                            {
                                coords: [
                                    [116.403039, 39.914023],
                                    [106.33, 29.35],
                                ],
                            },
                        ],
                    },
                ],
            };
            this.myChart.setOption(option, true);
        },
        goBack() {
            const mapList = this.mapList;
            if (mapList.length === 1) {
                this.initChinaMap();
                return;
            } else if (mapList.length == 2) {
                const areaName = this.highLightArea.pop();
                this.handleHighlightArea(areaName);
                this.initChinaMap();
                return;
            }
            // 获取当前地图的名称
            mapList.pop();
            const { name, adcode } = mapList[mapList.length - 1];
            this.getGeoJsonData({ name, adcode }, (data) => {
                this.renderChart(name, data);
            });
            this.mapList = mapList;
            const areaName = this.highLightArea.pop();
            this.handleHighlightArea(areaName);
            this.handleNavName();
        },
        // 导航
        handleNavName() {
            this.currentLocation = this.mapList
                .map((item) => item.name)
                .join(" > ");
        },
        handleHighlightArea(name = "") {
            setTimeout(() => {
                this.myChart.dispatchAction({
                    type: "geoSelect",
                    name,
                });
            }, 100);
        },
        clickReset() {
            this.highLightArea = [];
            this.initChinaMap();
        },
    },
};
</script>

<style lang="less" scoped>
.map {
    margin-top: 40px;
}
.wrapper {
    display: flex;
    align-items: center;
    margin-bottom: 10px;
    .info {
        margin-left: 60px;
    }
}
.map-container {
    width: 1000px;
    height: 800px;
    border: 1px solid #ccc;
}
</style>
